home *** CD-ROM | disk | FTP | other *** search
- #include <aesbind.h>
- #include <gemfast.h>
- #include <obdefs.h>
- #include <macros.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <vdibind.h>
-
- /* this should really go into a header file for debugging stuff */
- #ifndef NDEBUG
- #ifdef __TURBOC__
- static void _DEBUG(const char *s,...) \
- {vfprintf(stderr,s,...);fprintf(stderr,"\n");}
- /*static void _DEBUGL(const char *s,...) \
- {vfprintf(stderr,s,...);}*/
- #else
- static void _DEBUG(const char *s,...) \
- {vfprintf(stderr,s,(__VA_LIST__)__builtin_next_arg()); \
- fprintf(stderr,"\n");}
- /*static void _DEBUGL(const char *s,...) \
- {vfprintf(stderr,s,(__VA_LIST__)__builtin_next_arg());}*/
- #endif
- #define DEBUG(x) _DEBUG x
- #define DEBUGL(x) _DEBUGL x
- #else
- #define DEBUG(x)
- #define DEBUGL(x)
- #endif
-
- #define BUFSIZE 512
-
- typedef struct {
- unsigned int compression : 1;
- unsigned int reserved0 : 13;
- unsigned int resolution : 2;
- struct {
- unsigned int reserved1 : 5;
- unsigned int red : 3;
- unsigned int reserved2 : 1;
- unsigned int green : 3;
- unsigned int reserved3 : 1;
- unsigned int blue : 3; } palette[16];
- } DegasPic;
-
- static int vr_pal_trnfm(int vdihandle,unsigned short *colcnv,
- MFDB *source,MFDB *dest)
- /* convert standard to non-standard format, even if the amount of */
- /* planes does not match; handle palette conversion for vdi colors; */
- /* currently no more than sixteen vdicolors are supported (MAXCOL); */
- /* you can provide an array with sixteen entries for converting */
- /* your input colors to vdi colors. */
- /* Warning! if transformation between different colors/planes has */
- /* to be performed, this algorithm is very slow and (temporarly) */
- /* memory expensive! */
- {
- #define MAXPLANES 24
- #define MAXCOL 16
-
- static unsigned long vditab[MAXCOL]; /* cache for speed-up */
- static int dest_planes = -1;
- static int maxcol,trivial;
- unsigned short bios2vdi[MAXCOL];
- unsigned long col,lookup[MAXCOL];
- MFDB tmp_mfdb = *source;
-
- if (source->fd_stand == dest->fd_stand || /* ??? */
- !source->fd_stand || /* implementation */
- (1UL << source->fd_nplanes) > MAXCOL || /* restriction! */
- source->fd_nplanes > 8*sizeof(unsigned short) ||
- dest->fd_nplanes > MAXPLANES) { /* " */
- /* Call standard vr_trnfm() function if extended handling is*/
- /* not needed or not possible... */
- vr_trnfm(vdihandle,source,dest);
- return(1); }
- if (dest_planes != dest->fd_nplanes) { /* resolution change or */
- int plane; /* uninitialized vdi */
- MFDB m_std,m_nstd; /* lookup table... */
- unsigned long d_std[MAXPLANES],d_nstd[MAXCOL];
- int pxy[8],trans_col[2];
- dest_planes = dest->fd_nplanes;
- maxcol = (unsigned short)(min(MAXCOL,(1UL << dest_planes)));
- m_nstd.fd_addr = (long)d_nstd;
- m_nstd.fd_w = sizeof(unsigned long)*8;
- m_nstd.fd_h = 1;
- m_nstd.fd_wdwidth = sizeof(unsigned long)/2;
- m_nstd.fd_stand = 0;
- m_nstd.fd_nplanes = dest_planes;
- m_nstd.fd_r1 =
- m_nstd.fd_r2 =
- m_nstd.fd_r3 = 0;
- m_std = m_nstd;
- m_std.fd_addr = (long)d_std;
- m_std.fd_stand = 1;
- m_std.fd_nplanes = 1; /* for vrt_cpyfm */
- d_std[0] = ~0;
- memset(pxy,0,sizeof(pxy));
- trans_col[1] = 0;
- memset(d_nstd,0,sizeof(d_nstd));
- for (trans_col[0] = 0; trans_col[0] < maxcol; trans_col[0]++) {
- pxy[4] = pxy[6] = (8*(int)sizeof(unsigned long))-trans_col[0]-1;
- vrt_cpyfm(vdihandle,MD_TRANS,pxy,&m_std,&m_nstd,trans_col); }
- m_std.fd_nplanes = dest_planes;
- vr_trnfm(vdihandle,&m_nstd,&m_std);
- for (col = 0; col < maxcol; col++) {
- vditab[col] = 0;
- for (plane = 0; plane < dest_planes; plane++)
- if (d_std[plane] & (1UL << col))
- vditab[col] |= 1UL << plane; }
- for (col = maxcol; col < MAXCOL; col++)
- vditab[col] = vditab[maxcol-1]; }
- trivial = 1;
- if (colcnv) {
- int black = min(15,(int)((1UL << source->fd_nplanes)-1));
- for (col = MAXCOL; col--;)
- bios2vdi[col] = col < black ? colcnv[col] :
- col == black ? 1 : colcnv[col]; }
- for (col = MAXCOL; col--;)
- if ((lookup[col] = colcnv ?
- vditab[bios2vdi[col]] : vditab[col]) != col)
- trivial = 0;
- if ((!trivial || source->fd_nplanes != dest_planes)) {
- if ((tmp_mfdb.fd_addr = (long)malloc(2L*
- (long)source->fd_wdwidth*(long)source->fd_h*
- (long)dest_planes)) == 0L) {
- /* Sorry! Algorithm for splitting bit blocks and con- */
- /* serving some memory not yet implemented! */
- return(0); /* fail */ }
- else {
- unsigned long offset,index;
- unsigned short plane,bit;
- unsigned short *s_word,*ptr,*d_word;
- s_word = (unsigned short *)source->fd_addr;
- d_word = (unsigned short *)tmp_mfdb.fd_addr;
- offset = (unsigned long)source->fd_h*
- (unsigned long)source->fd_wdwidth;
- /* This loop *needs* optimization! Assembly language */
- /* might be a really good idea :-) */
- for (index = offset; index--; s_word++,d_word++) {
- for (plane = dest_planes, ptr = d_word;
- plane--;
- *ptr = 0, ptr += offset);
- for (bit = 8*sizeof(unsigned short); bit--;) {
- for (ptr = s_word, col = 0, plane = 0;
- plane < source->fd_nplanes;
- plane++, ptr += offset) {
- if (*ptr & (1U << bit))
- col |= 1UL << plane; }
- col = lookup[col%MAXCOL];
- for (ptr = d_word, plane = 0;
- plane < dest_planes;
- plane++, ptr += offset)
- if (col & (1U << plane))
- *ptr |= 1U << bit; } }
- tmp_mfdb.fd_nplanes = dest_planes;
- vr_trnfm(vdihandle,&tmp_mfdb,dest);
- free((void *)tmp_mfdb.fd_addr); } }
- else {
- vr_trnfm(vdihandle,source,dest); }
- return(1);
-
- #undef MAXPLANES
- #undef MAXCOL
- }
-
- static void separatebitplanes(MFDB *source,MFDB *dest)
- /* basically the same function as vr_trnfm(nstd,std) for standard */
- /* ST video modes; but you cannot call vr_trnfm() for converting */
- /* Degas Elite images, if you do not want to make assumption on the */
- /* video system... */
- {
- unsigned short *s,*d,*ptr;
- unsigned long offset,index;
- int plane;
-
- offset = (long)source->fd_wdwidth*(long)source->fd_h;
- s = (unsigned short *)source->fd_addr;
- d = (unsigned short *)dest->fd_addr;
- for (index = offset; index--; d++) {
- ptr = d;
- for (plane = source->fd_nplanes; plane--; ptr += offset)
- *ptr = *s++; }
- return;
- }
-
- static MFDB *loaddegas(int vdihandle,char *fname)
- {
- #define DATA(x) ((unsigned char *)((DegasPic *)(x)+1))
- #define getbyte() (pos < len ? buffer[pos++] : \
- len <= 0 ? -1 : \
- (pos = 0,len = (int)fread(buffer,1L,BUFSIZE,file)) \
- <= 0 ? -1 : buffer[pos++])
- static unsigned short colcnv[4][16] = {
- /* adapt this table as needed (your mileage may vary!)*/
- { 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1},
- { 0, 2, 2, 2, 2, 2, 2, 0, 0, 1, 1, 1, 1, 1, 1, 1},
- { 0, 2, 3, 6, 4, 7, 5, 8, 1, 2, 3, 6, 4, 7, 5, 1},
- { 0, 2, 3, 6, 4, 7, 5, 8, 9,10,11,14,12,15,13, 1}};
- static unsigned char buffer[BUFSIZE];
- FILE *file;
- int planes,workout[57];
- int pos,len;
- DegasPic *source;
- MFDB *m_source,m_dest;
- int splanes,x,y,p,b,w,h,c,inc,data = 0;
- unsigned char *d;
-
- vq_extnd(vdihandle,1,workout);
- planes = workout[4];
- if ((file = fopen(fname,"rb")) == NULL) {
- DEBUG(("file not found"));
- return(0); }
- if ((source = (void *)calloc(1,sizeof(DegasPic)+32000)) == NULL) {
- DEBUG(("out of memory"));
- fclose(file);
- return(0); }
- if ((len = (int)fread(buffer,1L,BUFSIZE,file)) < sizeof(DegasPic) ||
- source->resolution == 3) {
- DEBUG(("illegal file format"));
- free(source);
- fclose(file);
- return(0); }
- *source = *(DegasPic *)&buffer;
- pos = (int)sizeof(DegasPic);
- splanes = 1 << (2 - source->resolution);
- if (!source->compression) {
- memcpy(DATA(source),buffer+pos,BUFSIZE-sizeof(DegasPic));
- if (fread(DATA(source)+BUFSIZE-sizeof(DegasPic),1L,
- 32000-BUFSIZE+sizeof(DegasPic),file) !=
- 32000-BUFSIZE+sizeof(DegasPic)) {
- DEBUG(("file too short"));
- free(source);
- fclose(file);
- return(0); }
- switch (source->resolution) {
- case 0:
- w = 320; h = 200; break;
- case 1:
- w = 640; h = 200; break;
- case 2:
- w = 640; h = 400; break;
- default:
- DEBUG(("this cannot happen!"));
- free(source);
- fclose(file);
- return(0); }
- fclose(file); }
- else {
- source->compression = 0;
- switch (source->resolution) {
- case 0:
- w = 320; h = 200; break;
- case 1:
- w = 640; h = 200; break;
- case 2:
- w = 640; h = 400; break;
- default:
- DEBUG(("this cannot happen!"));
- free(source);
- fclose(file);
- return(0); }
- d = DATA(source);
- c = 0;
- inc = 1;
- for (y = 0; y < h; y++, d += (w/8-2)*splanes)
- for (p = 0; p < splanes; p++,d -= (w/8)*splanes-2)
- for (x = 0; x < w/16; x++, d += 2*(splanes-1))
- for (b = 0; b < 2; b++,d++) {
- if (!c) {
- do {
- c = getbyte();
- if (c == 128)
- DEBUG(("NOP found in compressed data"));
- else if (c == -1) {
- eof: DEBUG(("insufficient data"));
- free(source);
- fclose(file);
- return(0); }
- } while (c == 128);
- if (c > 128) {
- c = 257 - c; inc = 0;
- if ((data = getbyte()) == -1)
- goto eof; }
- else {
- c += 1; inc = 1; } }
- if (inc && ((data = getbyte()) == -1))
- goto eof;
- *d = data; c--; }
- fclose(file); }
- m_source = (MFDB *)malloc(sizeof(MFDB)+
- (long)w/8L*(long)h*
- (long)max(planes,splanes));
- if (m_source == NULL) {
- free(DATA(source));
- return(0); }
- m_source->fd_addr = (long)DATA(source);
- m_source->fd_w = w;
- m_source->fd_h = h;
- m_source->fd_wdwidth= m_source->fd_w / 16;
- m_source->fd_stand = 0;
- m_source->fd_nplanes= splanes;
- m_source->fd_r1 =
- m_source->fd_r2 =
- m_source->fd_r3 = 0;
- m_dest = *m_source;
- m_dest.fd_addr = (long)(m_source+1);
- m_dest.fd_stand = 1;
- separatebitplanes(m_source,&m_dest);
- memcpy(DATA(source),m_source+1,
- (long)w/8L*(long)h*(long)splanes);
- m_dest.fd_addr = (long)DATA(source);
- m_dest.fd_stand = 1;
- m_source->fd_addr = (long)(m_source+1);
- m_source->fd_nplanes= planes;
- m_source->fd_stand = 0;
- if (!vr_pal_trnfm(vdihandle,colcnv[splanes > 4 ? 3 : splanes-1],
- &m_dest,m_source)) {
- free(source);
- free((void *)m_source);
- return(0); }
- free(source);
- return(m_source);
-
- #undef DATA
- #undef getbyte
- }
-
- int main(int argc,char *argv[])
- {
- int vdihandle,workin[11],workout[57];
- int x,y,w,h,pxy[8];
- MFDB scr,*img;
-
- appl_init();
- memset(workin,0,sizeof(workin));
- workin[0] = vdihandle = graf_handle(&x,&y,&w,&h);
- workin[10] = 2;
- v_opnvwk(workin,&vdihandle,workout);
- x = y = 0;
- w = workout[0] + 1;
- h = workout[1] + 1;
- img = loaddegas(vdihandle,argc == 2 ? argv[1] : "DEMO.PC1");
- if (img != NULL) {
- wind_update(BEG_UPDATE);
- wind_update(BEG_MCTRL);
- form_dial(FMD_START,0,0,0,0,x,y,w,h);
- scr.fd_addr = 0;
- pxy[6] = pxy[2] = (pxy[4] = pxy[0] = x) + w - 1;
- pxy[7] = pxy[3] = (pxy[5] = pxy[1] = y) + h - 1;
- graf_mouse(M_OFF,0);
- vro_cpyfm(vdihandle,ALL_WHITE,pxy,&scr,&scr);
- pxy[2] = (pxy[0] = 0) + img->fd_w - 1;
- pxy[3] = (pxy[1] = 0) + img->fd_h - 1;
- pxy[6] = (pxy[4] = (w - img->fd_w) / 2) + img->fd_w - 1;
- pxy[7] = (pxy[5] = (h - img->fd_h) / 2) + img->fd_h - 1;
- vro_cpyfm(vdihandle,S_ONLY,pxy,img,&scr);
- graf_mouse(M_ON,0);
- evnt_keybd();
- form_dial(FMD_FINISH,0,0,0,0,x,y,w,h);
- wind_update(END_MCTRL);
- wind_update(END_UPDATE);
- free(img); }
- else
- DEBUG(("picture could not be loaded"));
- v_clsvwk(vdihandle);
- appl_exit();
- return(0);
- }
-